#!/usr/bin/env python
# coding: utf-8

############################################################################
#                   2012/05/29  Ver 1.8                                    #
#Release note:                                                             #
#1、Shen Yibo find when use the sript to download version to 13,           #
#   the ne's start filesys have not change, resolved the problem.          #
#2、More NE to ftp file at the same time, it will be failed, one variables #
#   must be reinitialized.                                                 #
#3、modify the pos restart flow post by Xiaodong Li                        #
#4、For the pos slot,if slot = 0,the script notice "invalid slot", not"skip#
#   and move the next"                                                     #
#5、Modify the menu information by the new upgrade flow revise             #
#6、Fixed the bug                                                          #
#7、Add the version check selection                                        #
############################################################################
#                   2012/07/11  Ver 1.9                                    #
#8、Modify the version check, N64F01 and N64F01(C0)                        #
############################################################################
#                   2012/07/19  Ver 1.11                                   #
#9、Add the /tffs/sys/ and /fs2/sys/ check                                 #
#10、Modify the log file save location                                     #
############################################################################
#                   2012/08/15  Ver 1.12                                   #
#11、Add auto creat the /tffs/sys and /fs2/sys                             #
#12、Add a selection for ingnore lsp errlog = 19 in sync check             #
############################################################################




"""
文件名：sbb_upgrade_downgrade_flow.py
作  者：fancl
时  间: 2012-3-20
功能描述：
    这个是升级的主体程序，实现SBB提出的升级流程，按照功能分解，需分别实现以下模块：
    1、	FTP批处理传送文件（软件+BIOS+CPLD）
    2、	升级OPCA（软件+BIOS）
    3、	升级POS（软件+CPLD）
    4、	升级CM48E16(S)（软件）
    5、 版本信息校验
"""
import re
import os
import sys
import time
import datetime
import string
import getpass

from sbb_upgrade_downgrade_software import *

cpld_version_dict = {
    "5":"V1.1.0.1",
    "6":"V1.1.0.1",
    "7":"V1.1.0.1",
    "8":"V1.1.0.1"
}

bios_version_dict = {
    "3":"V3.6.2.2",
    "4":"V3.6.2.2",
    "5":"V3.5.2.1",
    "6":"V3.5.2.1",
    "7":"V3.5.2.1",
    "8":"V3.5.2.1",
}

software_version_dict = {
    "3":"V1.3.2.18_sp8",
    "4":"V1.3.2.18_sp8",
    "5":"V1.3.2.18_sp8",
    "6":"V1.3.2.18_sp8",
    "7":"V1.3.2.18_sp8",
    "8":"V1.3.2.18_sp8"
}

#保存前面一步的ftp是否成功
ftp_results_dic = {}

log_node_summary            = "upgrade_summary"
log_node_fail               = "upgrade_fail"
log_node_success            = "upgrade_success"
log_node_operation          = "upgrade_operation"

log_file_not_existed        = "the file:%s isn't existed\n"

log_cpld_upgrade_success    = "upgrade cpld ip:%s slot:%s success\n"
log_cpld_upgrade_fail       = "upgrade cpld ip:%s slot:%s fail\n"

log_bios_upgrade_success    = "upgrade bios ip:%s slot:%s success\n"
log_bios_upgrade_fail       = "upgrade bios ip:%s slot:%s fail\n"

log_sys_set_success         = "the setup sys ip:%s slot:%s set success"
log_sys_set_fail            = "the setup sys ip:%s slot:%s set fail"

log_get_fail                = "get ip:%s failed\n"
log_put_opca_fail           = "put ip:%s slot:%s opca file failed\n"
log_put_pos_fail            = "put ip:%s pos file failed\n"            
log_upgrade_fail            = "upgrade ip:%s slot:%s failed\n"

log_connect_success         = "connect ip:%s success\n"
log_register_value_success  = "ip:%s slot:%s register:%d value:%d success\n"

log_get_success             = "get ip:%s success\n"
log_put_opca_success        = "put ip:%s slot:%s opca file success\n"
log_put_pos_success         = "put ip:%s pos file success\n"
log_upgrade_success         = "upgrade ip:%s slot:%s success\n"
log_non64f01_success        = "ip:%s have no n64f01 card or no n64f01 card need to upgrade CPLD\n"


log_connect_fail            = "ip:%s connect failed\n"
log_connect_slot_fail       = "connect ip:%s slot:%s failed\n"

log_delete_fail             = "delete ip:%s slot:%s file:%s failed\n"
log_put_fail                = "cd ip:%s backupsys:%s and put slot:%s file:%s failed\n"
log_md5_fail                = "ip:%s slot:%s file:%s md5 failed\n"
log_upgrade_fail            = "ip:%s slot:%s upgrade failed\n"

log_connect_success         = "ip:%s connect success\n"
log_delete_success          = "delete ip:%s slot:%s file:%s success\n"
log_put_success             = "cd ip:%s filesys:%s and put slot:%s file:%s success\n"
log_md5_success             = "ip:%s slot:%s file:%s md5 success\n"

log_register_value_success  = "ip:%s slot:%s register:%d value:%d success\n"
log_check_version           = "check ip:%s slot:%s type:%s current version %s dest version %s result:%s\n"

log_file_notexisted_fail    = "the file:%s isn't existed\n"
log_master_opca_fail        = "ip:%s get master opca is failed\n"
log_opca_slotlist_fail      = "ip:%s get opca slot list is failed\n"
log_connect_fail            = "ip:%s connect failed\n"
log_checkhw_fail            = "ip:%s slot:%s checkhw failed\n"
log_checkhw_lsp_fail        = "ip:%s slot:%s checkhw lsp failed\n"
log_checkhw_pw_fail         = "ip:%s slot:%s checkhw pw failed\n"
log_checkhw_ethpw_fail      = "ip:%s slot:%s checkhw ethpw failed\n"
log_check_linkstatus_fail   = "ip:%s unit:%s port:%s linkstatus is not synced\n"
log_check_phystatus_fail    = "ip:%s unit:%s port:%s phystatus is not synced\n"
log_check_nms_sync_fail     = "ip:%s nms sync is fail"
log_sync_status_fail        = "ip:%s all sync information checked fail!"


log_one_opca_success        = "ip:%s only have one opca card, need not do sync check\n"
log_master_opca_success     = "ip:%s master opca is %d\n"
log_checkhw_success         = "ip:%s slot:%s checkhw success\n"
log_checkhw_lsp_success     = "ip:%s slot:%s checkhw lsp success\n"
log_checkhw_pw_success      = "ip:%s slot:%s checkhw pw success\n"
log_checkhw_ethpw_success   = "ip:%s slot:%s checkhw ethpw success\n"
log_check_linkstatus_success= "ip:%s linkstatus is synced\n"
log_check_phystatus_success = "ip:%s phystatus is synced\n"
log_check_nms_sync_success  = "ip:%s nms sync is success"
log_sync_status_success     = "ip:%s all sync information checked success!"

log_summary_success         = "ip:%s success\n"
log_summary_fail            = "ip:%s fail\n"


upgrade_slot_opca_dic = {
    "OPCA":     [],
}

upgrade_slot_pos_dic = {
}

upgrade_slot_pos_c0_dic = {
}

restart_slot_dic = {                  
}
                    
class TestCase(SbbUpgradeDowngradeSoftware):
    """
    TestCase
    """
    OPTIONS = [
        {
            'opt' : '--cfgfile',
            'dest': 'cfgfile',
            'metavar' : 'PATH',
            'help' : 'the file of ip list configuration',
            'required' : False,
            'default' : "ip.txt"
        },
        {
            'opt' : '--path',
            'dest': 'path',
            'metavar' : 'PATH',
            'help' : 'the directory of 705upgrade',
            'required' : False,
            'default' : "D:/heavysmoker/workspace/suites/info_collect/v1.3.2.18_sp8(SBB)"
        },
        {
            'opt' : '--md5',
            'dest': 'md5',
            'metavar' : 'md5',
            'help' : 'the enable of md5 check',
            'required' : False,
            'default' : "True"
        },
        {
            'opt' : '--md5file',
            'dest': 'md5file',
            'metavar' : 'md5file',
            'help' : 'the file of md5 ',
            'required' : False,
            'default' : "md5file.txt"
        },
        {
            'opt' : '--verlistfile',
            'dest': 'verlistfile',
            'metavar' : 'verlistfile',
            'help' : 'the file of version ',
            'required' : False,
            'default' : "version.txt"
        },
        {
            'opt' : '--autoupgrade',
            'dest': 'autoupgrade',
            'metavar' : 'autoupgrade',
            'help' : 'auto execute upgrade flow',
            'required' : False,
            'default' : "False"
        },
        {
            'opt' : '--bios',
            'dest': 'bios',
            'metavar' : 'bios',
            'help' : 'the enable of upgrade bios',
            'required' : False,
            'default' : "True"
        },
        {
            'opt' : '--cpld',
            'dest': 'cpld',
            'metavar' : 'cpld',
            'help' : 'the enable of upgrade cpld',
            'required' : False,
            'default' : "True"
        },
        {
            'opt' : '--onlycpld',
            'dest': 'onlycpld',
            'metavar' : 'onlycpld',
            'help' : 'the enable of onlycpld for 15 and 13',
            'required' : False,
            'default' : "False"
        },
    ]     
    
    def info_init(self):
        self.info_dic = {}
        
        self.log_node_summary            = log_node_summary
        self.log_node_fail               = log_node_fail
        self.log_node_success            = log_node_success
        self.log_node_operation          = log_node_operation
        
        self.log_put_opca_success        = log_put_opca_success
        self.log_put_pos_success         = log_put_pos_success
        
        self.log_cpld_upgrade_success    = log_cpld_upgrade_success
        self.log_cpld_upgrade_fail       = log_cpld_upgrade_fail
        
        self.log_bios_upgrade_success    = log_bios_upgrade_success
        self.log_bios_upgrade_fail       = log_bios_upgrade_fail

        self.log_sys_set_success         = log_sys_set_success
        self.log_sys_set_fail            = log_sys_set_fail
        
        self.log_file_not_existed        = log_file_not_existed 
        self.log_connect_fail            = log_connect_fail
        self.log_connect_slot_fail       = log_connect_slot_fail
        
        self.log_delete_fail             = log_delete_fail
        self.log_put_fail                = log_put_fail
        self.log_md5_fail                = log_md5_fail        
        self.log_upgrade_fail            = log_upgrade_fail
        self.log_put_pos_fail            = log_put_pos_fail
        
        self.log_connect_success         = log_connect_success
        self.log_delete_success          = log_delete_success
        self.log_put_success             = log_put_success
        self.log_md5_success             = log_md5_success        
        
        self.log_register_value_success  = log_register_value_success
        
        self.log_file_notexisted_fail    = log_file_notexisted_fail
        self.log_master_opca_fail        = log_master_opca_fail
        self.log_opca_slotlist_fail      = log_opca_slotlist_fail
        self.log_connect_fail            = log_connect_fail
        self.log_checkhw_fail            = log_checkhw_fail
        self.log_checkhw_lsp_fail        = log_checkhw_lsp_fail
        self.log_checkhw_pw_fail         = log_checkhw_pw_fail
        self.log_checkhw_ethpw_fail      = log_checkhw_ethpw_fail
        self.log_check_linkstatus_fail   = log_check_linkstatus_fail
        self.log_check_phystatus_fail    = log_check_phystatus_fail
        self.log_check_nms_sync_fail     = log_check_nms_sync_fail
        self.log_sync_status_fail        = log_sync_status_fail
        
        self.log_one_opca_success        = log_one_opca_success
        self.log_master_opca_success     = log_master_opca_success
        self.log_checkhw_success         = log_checkhw_success
        self.log_checkhw_lsp_success     = log_checkhw_lsp_success
        self.log_checkhw_pw_success      = log_checkhw_pw_success
        self.log_checkhw_ethpw_success   = log_checkhw_ethpw_success
        self.log_check_linkstatus_success= log_check_linkstatus_success
        self.log_check_phystatus_success = log_check_phystatus_success
        self.log_check_nms_sync_success  = log_check_nms_sync_success
        self.log_sync_status_success     = log_sync_status_success
        
        
        self.log_summary_success         = log_summary_success
        self.log_summary_fail            = log_summary_fail
    
        self.log_check_version           = log_check_version
        
        self.cpld_version_dict           = cpld_version_dict
        self.bios_version_dict           = bios_version_dict
        self.software_version_dict       = software_version_dict
        
        self.version_dic = {}
                
        self.bios_name = ''
        self.cpld_name = ''
        
        return True 
    
    #以node为关键字，把信息保存到info_dic[node]中。
    def info_show(self, node, info):
        if not self.info_dic.has_key(node):
            self.info_dic[node] = ""
        self.info_dic[node] += info + '\n'        
        return True    
            
    def info_file_save(self):
        path = self.work_path+'/'+self.logfolder+'//'
        if not os.path.isdir(path):
            os.makedirs(path)
        
        for node in self.info_dic:
            info_list = open(path+node+'_'+self.worktime+'.txt','a')            
            info_list.write(self.info_dic[node])
            info_list.close()
            
        return True
    
    def get_iplist(self):
        iplist_filted = []                
        if os.path.isfile(os.getcwd()+r'/'+ self.iplistfile):
            iplist = open(os.getcwd()+r'/'+ self.iplistfile)
            #self.info_show(log_node_info, "The iplist file %s is existed."%(self.iplistfile)) 
        else:
            self.info_show(self.log_node_fail, self.log_file_not_existed%(self.iplistfile))            
            return iplist_filted 
        
        for line in iplist:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注释行            
            iplist_filted.append(line.strip('\n'))        
            
        iplist.close()
        
        return iplist_filted
    
    def get_dest_version_dic(self):
        dest_version_dic = {}
        
        if os.path.isfile(os.getcwd()+r'/'+ self.versionlistfile):
            version_list_line = open(os.getcwd()+r'/'+ self.versionlistfile)
            #self.info_show(log_node_info, "The iplist file %s is existed."%(self.iplistfile)) 
        else:
            self.info_show(self.log_node_fail, self.log_file_not_existed%(self.versionlistfile))            
            return False 
        
        for line in version_list_line:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注释行
            
            version_list = re.findall(r"^(.+),(.+),(.+),(.+),(.+),(.+),(.+\d+)\n*", line, re.I)
            
            #[Card][Software][BIOS][BSP][FPGA1][FPGA2][CPLD]
            if version_list[0][0] == "CM48E16" or version_list[0][0] == "CM48E16S":
                cpld_list = re.split(r'or',version_list[0][6])
                dest_version_dic.setdefault(version_list[0][0],[(cpld_list,version_list[0][4],version_list[0][5])])
            elif version_list[0][0] == "CGF12" or version_list[0][0] == "CGF12S" or version_list[0][0] == "NXGF01" or version_list[0][0] == "NXGF01S":
                cpld_list = re.split(r'or',version_list[0][6])
                dest_version_dic.setdefault(version_list[0][0],[(cpld_list,)])
            elif version_list[0][0] == "OPCA" or version_list[0][0] == "N64F01" or version_list[0][0] == "N16F01" or version_list[0][0] == "N64F01(C0)":
                cpld_list = re.split(r'or',version_list[0][6])
                dest_version_dic.setdefault(version_list[0][0],[(cpld_list,version_list[0][4]),(version_list[0][2],version_list[0][3],version_list[0][1])])
    
        version_list_line.close()
        
        return dest_version_dic
    
    #初始化成员变量
    def init_member_variables(self):
        #单个网元开始升级初始化开始就算出
        self.upgrade_slot_opca_dic =  upgrade_slot_opca_dic
        self.upgrade_slot_pos_dic = upgrade_slot_pos_dic
        self.restart_slot_dic =    restart_slot_dic      
        self.upgrade_slot_pos_c0_dic = upgrade_slot_pos_c0_dic
        
        self.slot_backupsys_list = []
        self.bsp_bios_file_list_standby = []
        self.bsp_bios_slot_list_standby = []
        self.bsp_bios_file_list_active = []
        self.bsp_bios_slot_list_active = []
        
        return True
    
    def restart_card_hard(self, slot):
        self.info_show(self.log_node_operation, "   restart card slot %d hard .\n" % slot)
         
        cmd = r'configure terminal'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), 0, CLI_PORT)
         
        cmd = r'restart %d hard' % slot
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), 0, CLI_PORT)
        
        cmd = r'exit'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), 0, CLI_PORT)
        #冷复位以后等待5min
        self.my_sleep(300)
         
        
        return True
    
    #得到CPLD需要升级的槽位
    #主要是查找5，6，7，8槽位上面的POS板
    def get_upgrade_slot_dic(self, upgrade_file_dic):
        if upgrade_file_dic is None:
            return {}
        
        slot_list = [5,6,7,8]
                    
        rtn = self.tnxxx.send_rtn_str("show card", self.get_ne_ip(0), 0, CLI_PORT)
        card_info_list = re.findall(r"slot:\s+(\d+)\s+(?:--More--\s+)?stat:\s+\w+\s+(?:--More--\s+)?Card:\s+(\w+)\s+", rtn, re.I)
        upgrade_slot_dic = {}
        for card_info in card_info_list:
            slot = int(card_info[0])
            if slot not in slot_list : continue            
           
            card_name = card_info[1].upper() #转化为大写，dic中的都是大写
            
            #在文件字典中查找对应的KEY文件
            if not upgrade_file_dic.has_key(card_name) : continue
            
            ###########################################################################
            #以下代码得到需要升级的POS板槽位字典，key = cardtype， value = [solt_list]#
            ###########################################################################
            #获取0xb（PCB版本）寄存器的值
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0xb*4)&0xf", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                pcb_value = rtn_str.group()[2:]
                self.info_show(self.log_node_operation, log_register_value_success%(self.get_ne_ip(0),slot,11,int(pcb_value)))
                
            #获取0x4,0x5（CPLD版本）寄存器的值
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0x4*4)&0xff", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                cpldbig_value = rtn_str.group()[2:]
                self.info_show(self.log_node_operation, log_register_value_success%(self.get_ne_ip(0),slot,4,int(cpldbig_value)))
                
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0x5*4)&0xff", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                cpldsmall_value = rtn_str.group()[2:]
                self.info_show(self.log_node_operation, log_register_value_success%(self.get_ne_ip(0),slot,5,int(cpldsmall_value)))
          
                   
            #调试，先关闭校验                
            #if not (int(pcb_value) >=2 and int(cpldbig_value) != 0x11 and int(cpldsmall_value) != 0x1):
            if not (int(pcb_value) >=2):
                self.info_show(self.log_node_success, "Check Install Card:Slot%d don't need CPLD upgrade!\n" % slot)
                continue
            
            if not upgrade_slot_dic.has_key(card_name):
                upgrade_slot_dic[card_name] = []
            upgrade_slot_dic[card_name].append(slot)
            self.info_show(self.log_node_success, "Check Install Card:Slot%d need CPLD upgrade!\n" % slot)
            
        return upgrade_slot_dic

    #得到N64F01(C0)槽位
    #主要是查找5，6，7，8槽位上面的POS板
    def get_n64f01c0_slot_dic(self, upgrade_file_dic):
        if upgrade_file_dic is None:
            return {}
        slot_list = [5,6,7,8]
                    
        rtn = self.tnxxx.send_rtn_str("show card", self.get_ne_ip(0), 0, CLI_PORT)
        card_info_list = re.findall(r"slot:\s+(\d+)\s+(?:--More--\s+)?stat:\s+\w+\s+(?:--More--\s+)?Card:\s+(\w+)\s+", rtn, re.I)
        upgrade_slot_dic = {}
        for card_info in card_info_list:
            slot = int(card_info[0])
            if slot not in slot_list : continue            
           
            card_name = card_info[1].upper() #转化为大写，dic中的都是大写
            
            #在文件字典中查找对应的KEY文件
            if not upgrade_file_dic.has_key(card_name) : continue
            ###########################################################################
            #以下代码得到需要升级的POS板槽位字典，key = cardtype， value = [solt_list]#
            ###########################################################################
            #获取0xb（PCB版本）寄存器的值
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0xb*4)&0xf", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                pcb_value = rtn_str.group()[2:]
                self.info_show(self.log_node_operation, log_register_value_success%(self.get_ne_ip(0),slot,11,int(pcb_value)))
                
            #pcb版本大于2的为新版             
            if int(pcb_value) >= 2:  
                if not upgrade_slot_dic.has_key(card_name):
                    upgrade_slot_dic[card_name] = []
                upgrade_slot_dic[card_name].append(slot)
                self.info_show(self.log_node_success, "Check Install Card:Slot%d is A2 Card!\n" % slot)
            
        return upgrade_slot_dic
    
    def check_sys_folder(self):
        #如果是两块OPCA单板，需要确保"/tffs/sys/"和"/fs2/sys/"在23端口下可以show出来
        
        #先恢复下系统目录
        cmd = r'chkdsk "/tffs",2,0xff00'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        cmd = r'chkdsk "/fs2",2,0xff00'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        cmd = r'chkdsk "/tffs",2,0xff00'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        cmd = r'chkdsk "/fs2",2,0xff00'
        rtn = self.tnxxx.send_rtn_str(cmd , self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        
        #主OPCA的文件系统check
        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        query_tffs_sys_active = re.search("Can't", rtn_str)
        
        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        query_tffs_sys_active_tffs = re.search("Can't", rtn_str)
        
        #如果不存在目录，就创建
        if  query_tffs_sys_active == None:
            print "Check the /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
        else:
            if  query_tffs_sys_active_tffs == None:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /tffs/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                else:
                    print "mkdir /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                    #创建以后再检查一次
                    rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                    query_tffs_sys_active = re.search("Can't", rtn_str)
            else:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /tffs/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                else:
                    print "mkdir /tffs/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                    rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                    if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                        self.info_show(self.log_node_fail,  "mkdir /tffs/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                    else:
                        print "mkdir /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                        #创建以后再检查一次
                        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                        query_tffs_sys_active = re.search("Can't", rtn_str)
 
 
        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        query_fs2_sys_active = re.search("Can't", rtn_str)    
    
        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
        query_tffs_sys_active_fs2 = re.search("Can't", rtn_str)
        
        #如果不存在目录，就创建
        if  query_fs2_sys_active == None:
            print "Check the /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
        else:
            if  query_tffs_sys_active_fs2 == None:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /fs2/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                else:
                    print "mkdir /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                    #创建以后再检查一次
                    rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                    query_fs2_sys_active = re.search("Can't", rtn_str)
            else:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /fs2/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                else:
                    print "mkdir /fs2/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                    rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                    if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                        self.info_show(self.log_node_fail,  "mkdir /fs2/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[0][0]))
                    else:
                        print "mkdir /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[0][0])
                        #创建以后再检查一次
                        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[0][0], DEV_PORT)
                        query_fs2_sys_active = re.search("Can't", rtn_str)


        #备OPCA的文件系统check
        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        query_tffs_sys_standby = re.search("Can't", rtn_str)
        
        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        query_tffs_sys_standby_tffs = re.search("Can't", rtn_str)
        
        #如果不存在目录，就创建
        if  query_tffs_sys_standby == None:
            print "Check the /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
        else:
            if  query_tffs_sys_standby_tffs == None:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /tffs/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                else:
                    print "mkdir /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                    #创建以后再检查一次
                    rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                    query_tffs_sys_standby = re.search("Can't", rtn_str)

            else:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /tffs/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                else:
                    print "mkdir /tffs/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                    rtn_str = self.tnxxx.send_rtn_str('mkdir "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                    if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                        self.info_show(self.log_node_fail,  "mkdir /tffs/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                    else:
                        print "mkdir /tffs/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                        #创建以后再检查一次
                        rtn_str = self.tnxxx.send_rtn_str('ll "/tffs/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                        query_tffs_sys_standby = re.search("Can't", rtn_str)
 
 
        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        query_fs2_sys_standby = re.search("Can't", rtn_str)    
    
        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
        query_fs2_sys_standby_fs2 = re.search("Can't", rtn_str)
        
        #如果不存在目录，就创建
        if  query_fs2_sys_standby == None:
            print "Check the /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
        else:
            if  query_fs2_sys_standby_fs2 == None:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /fs2/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                else:
                    print "mkdir /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                    #创建以后再检查一次
                    rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                    query_fs2_sys_standby = re.search("Can't", rtn_str)
            else:
                rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                    self.info_show(self.log_node_fail,  "mkdir /fs2/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                else:
                    print "mkdir /fs2/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                    rtn_str = self.tnxxx.send_rtn_str('mkdir "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                    if re.search("value\s+=\s+0\s+=\s+0x0", rtn_str) == None:
                        self.info_show(self.log_node_fail,  "mkdir /fs2/sys/ fail, slot = %d\n" % int(self.slot_backupsys_list[1][0]))
                    else:
                        print "mkdir /fs2/sys/ success, slot = %d\n" % int(self.slot_backupsys_list[1][0])
                        #创建以后再检查一次
                        rtn_str = self.tnxxx.send_rtn_str('ll "/fs2/sys/"', self.get_ne_ip(0), self.slot_backupsys_list[1][0], DEV_PORT)
                        query_fs2_sys_standby = re.search("Can't", rtn_str)
                        
                    
        if (query_tffs_sys_active == None) and (query_fs2_sys_active == None) and (query_tffs_sys_standby == None) and (query_fs2_sys_standby == None):
            return True
        else:
            return False
        
        
    #得到当前的升级槽位
    def get_restart_slot_information(self):
        #记录操作流程
        self.info_show(self.log_node_operation, "NE IP: %s \n   Get all restart slot opca,pos,cm48e16 etc.\n" % self.get_ne_ip(0))
        card_tpye_list = ["OPCA","N64F01","N16F01","CM48E16","CM48E16S","CGF12", "CGF12S","NXGF01","NXGF01S"]
        card_tpye_pos_list = ["N64F01","N16F01"]
             
        #get ne's two opca card's backup boot sys
        #返回值是list = [[slot, backsys],...],其中0位置的是当前active的OPCA
        self.slot_backupsys_list=self.get_slot_backupsys_list(self.get_ne_ip(0))
        #记录操作流程
        self.info_show(self.log_node_operation, "   get the opca's backupsys for upgrade the new version files.\n")
        #get ne's actual opca slot need to be upgraded, the first element is active opca,so ensure upgrade active opca first.
        if len(self.slot_backupsys_list) < 2:
            #记录操作流程
            print "There are one opca, quit the upgrade!-------------------fail!\n"
            self.info_show(self.log_node_fail, "There are one opca, quit the upgrade!-------------------fail!\n")
            return False
        if self.check_sys_folder():
            self.info_show(self.log_node_success, "check the /tffs/sys and /fs2/sys/ folder success!\n")
        else:
            #记录操作流程
            print "check the /tffs/sys and /fs2/sys/ folder, quit the upgrade!-------------------fail!\n"
            self.info_show(self.log_node_fail, "check the /tffs/sys and /fs2/sys/ folder, quit the upgrade!-------------------fail!\n")
            return False
        #先清空一下列表
        self.upgrade_slot_opca_dic["OPCA"] = []
        for slot_backupsys in self.slot_backupsys_list:
            #将需要升级的槽位号添加到字典的
            self.upgrade_slot_opca_dic["OPCA"].append(slot_backupsys[0])
            
        #得到需要升级的POS板
        self.upgrade_slot_pos_dic = self.get_upgrade_slot_dic(self.upgrade_file_dic)
        
        self.upgrade_slot_pos_c0_dic = self.get_n64f01c0_slot_dic(self.upgrade_file_dic)
        
        #如果没有单板的槽位，需要赋值空列表
        for card_type in card_tpye_pos_list:
            if not self.upgrade_slot_pos_dic.has_key(card_type):
                self.upgrade_slot_pos_dic[card_type] = []
       
        #如果没有单板的槽位，需要赋值空列表
        for card_type in card_tpye_pos_list:
            if not self.upgrade_slot_pos_c0_dic.has_key(card_type):
                self.upgrade_slot_pos_c0_dic[card_type] = []
                
        #得到当前的复位槽位1，2，3，4，5，6，7，8
        self.restart_slot_dic = self.check_card_install()
         #如果没有单板的槽位，需要赋值空列表
        for card_type in card_tpye_list:
            if not self.restart_slot_dic.has_key(card_type):
                self.restart_slot_dic[card_type] = []
                
        return True
    
    def ftp_file_to_opca_and_pos(self):
        
        #先删除备用系统上面的软件
        if not self.del_old_files_opca(self.upgrade_file_dic, self.upgrade_slot_opca_dic):
            #记录操作流程
            self.info_show(self.log_node_fail, "   del files in two opca's backsys-------------------fail!\n")
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_success, "   del files in two opca's backsys-------------------success!\n")
        
        #传文件到OPCA
        if not self.upgrade_files_opca(self.upgrade_file_dic, self.upgrade_slot_opca_dic):
            #记录操作流程
            self.info_show(self.log_node_fail, "   ftp files to opca-------------------fail!\n")
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_success, "   ftp files to opca-------------------success.\n")
        
        #传文件到POS
        #self.slot_backupsys_list[0]第一个元素就是当前的主用PPC板
        if not self.upgrade_files_pos(self.upgrade_file_dic, self.upgrade_slot_pos_dic, self.slot_backupsys_list[0][0]):
            #记录操作流程
            self.info_show(self.log_node_fail, "   ftp files to pos-------------------fail!\n")
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_operation, "   ftp files to pos.\n")
        return True

    def ftp_file_to_pos(self):  
        #传文件到POS
        #self.slot_backupsys_list[0]第一个元素就是当前的主用PPC板
        if not self.upgrade_files_pos(self.upgrade_file_dic, self.upgrade_slot_pos_dic, self.slot_backupsys_list[0][0]):
            #记录操作流程
            self.info_show(self.log_node_fail, "   ftp files to pos-------------------fail!\n")
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_operation, "   ftp files to pos.\n")
        return True
    
    
    def get_bios_file_and_slot(self):     
        if len(self.slot_backupsys_list) > 1:
            for upgrade_file in self.upgrade_file_dic["OPCA"]:
                if upgrade_file[1] == self.bios_name:
                    self.bsp_bios_file_list_standby.append([self.slot_backupsys_list[1][1], deepcopy(upgrade_file[2]), deepcopy(upgrade_file[3])])
                    self.bsp_bios_file_list_active.append([self.slot_backupsys_list[0][1], deepcopy(upgrade_file[2]), deepcopy(upgrade_file[3])])                   
            self.bsp_bios_slot_list_standby.append(self.slot_backupsys_list[1][0])
            self.bsp_bios_slot_list_active.append(self.slot_backupsys_list[0][0])
        else:
            #只有一块OPCA不做升级
            return False
        return True
    
    def download_standby_opca_bios(self):
        active_opca_slot  =  self.slot_backupsys_list[0][0]
        bsp_bios_file_list_standby  = self.bsp_bios_file_list_standby
        bsp_bios_slot_list_standby  = self.bsp_bios_slot_list_standby
        
         
        if not self.bsp_download_bios_file(bsp_bios_file_list_standby, bsp_bios_slot_list_standby, active_opca_slot):
            #记录操作流程
            self.info_show(self.log_node_fail, "   bsp download bios file for standby opca-------------------fail!\n")
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_success, "   bsp download bios file for standby opca-------------------success.\n")
     
        
        return True
    
    
    def download_active_opca_bios(self):
        active_opca_slot  =  self.slot_backupsys_list[0][0]
        bsp_bios_file_list_active  = self.bsp_bios_file_list_active
        bsp_bios_slot_list_active  = self.bsp_bios_slot_list_active
        
        if not self.bsp_download_bios_file(bsp_bios_file_list_active, bsp_bios_slot_list_active, active_opca_slot):
            self.info_show(self.log_node_fail, "   bsp download bios file for active opca-------------------fail!\n")
            #失败直接退出循环while  True------standby 同步校验
            return False
        else:
            #记录操作流程
            self.info_show(self.log_node_success, "   bsp download bios file for active opca------------------success.\n")
         
        
        return True
    
    def wait_ne_sync(self):
        #需要加入一个超时机制，count_sync_timeout_active > 4失败返回
        count_sync_timeout = 1
        while True:                                    
            #检查单板起来以后是否同步
            if self.check_ne_sync():
                #同步校验成功退出while
                break
            else:
                self.info_show(self.log_node_operation, "   after opca restart, synchronized failed, and try %d times.\n" % count_sync_timeout)
                count_sync_timeout = count_sync_timeout + 1
                #再延时5分钟
                self.my_sleep(300)
                if count_sync_timeout > 4:
                    #复位以后同步校验失败超时返回
                    self.info_show(self.log_node_operation, "   after opca restart, synchronized failed, time out!\nCheck the ne status!!!.\n")
                    print "After opca restart, synchronized failed, time out!\nCheck the ne status!!!.\n"
                    #同步失败以后需要返回，而不是继续下一步
                    return False
        return True
    
    def download_pos_cpld(self, slot):
        jtag_cpld_file_list = []
        jtag_cpld_slot_list = []
        
        for upgrade_file in self.upgrade_file_dic["N64F01"]:
            if upgrade_file[1] == self.cpld_name:
                jtag_cpld_file_list.append([tffs_dir, deepcopy(upgrade_file[2]), deepcopy(upgrade_file[3])])
        jtag_cpld_slot_list.append(slot)
        
        #得到file 和 slot以后就烧写CPLD                        
        if not self.bsp_jtag_download_cpld_file(jtag_cpld_file_list, jtag_cpld_slot_list):
            self.info_show(self.log_node_fail, "   bsp jtag download cpld for pos slot %d--------------------fail.\n" % slot)
            return False
        else:
            self.info_show(self.log_node_success, "   bsp jtag download cpld for pos slot %d--------------------success.\n" % slot)
        
        #烧写以后等待一会儿
        self.my_sleep(120)
        #升级CPLD以后自动
        self.restart_card_hard(slot)
        
        return True
    
    def get_the_customer_input(self, note):
        rtnstr  = raw_input(note)
        while True:
            if rtnstr.upper() == "Y" or   rtnstr.upper() == "N":
                break
            else:
                rtnstr  = raw_input("Input < y or n > :\n")
                
        return    rtnstr.upper()
    
    def my_sleep(self, seconds):
        for minutes in range(0, seconds/60):
            for second in range(0,12):
                print "Countdown-Minutes:Second = %d : %d" % (((seconds/60) - minutes - 1), (59 - second*5))
                time.sleep(5)
    
    def cpld_bios_md5_list(self):
        md5_list = []
                
        if os.path.isfile(os.getcwd()+r'/'+ self.md5file):
            md5list = open(os.getcwd()+r'/'+ self.md5file)
        else:
            self.info_show(self.log_node_fail, self.log_file_not_existed%(self.md5file))            
            return md5_list 
        
        i = 0
        for md5num in md5list:
            if re.match(r'^\s*$', md5num) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', md5num) is not None : continue # 忽略注释行
            #get the bios and cpld's name
            filename_md5list = re.split(',',md5num.rstrip())
            
            if 0 == i:
                self.bios_name = filename_md5list[0]
                md5_list.append(filename_md5list[1])
            else:
                self.cpld_name = filename_md5list[0]
                md5_list.append(filename_md5list[1])
            
            i = i + 1
            
        md5list.close()
        
        return md5_list
    
    def choose_restart_hard_emu(self, cardtype):
        slot_emu_list = self.restart_slot_dic[cardtype]
        
        if [] != slot_emu_list:
            #循环显示需要复位的槽位，直到输入0结束该流程
            while [] != slot_emu_list:
                stremu = ''
                for slot in slot_emu_list:
                    strtemp = "\n%d: Slot%d restart hard now!" % (slot,slot)
                    stremu = stremu + strtemp
                note = "\n\n\nPlease select %s Card to execute card reboot.\n%s\nskip: Skip and move to next action.\n\nPlease input:" % (cardtype, stremu)
                str_input = raw_input(note)
                
                if str_input.isdigit():
                    slotemu = int(str_input)
                    
                    """
                    if 0 == slotemu:
                        #槽位为0退出循环
                        break
                    """
                    
                    #非列表中的槽位，继续
                    if slotemu not in slot_emu_list:
                        continue
                    while True:                                
                        if slotemu in slot_emu_list:
                            break
                        else:
                            str_input  = raw_input("Slot list:%s\nPlease input the valid slot:\n" % slot_emu_list)
                            
                            if str_input.isdigit():
                                slotemu = int(str_input)
                    
                    note = "Please confirm it again.It will execute card reboot on slot %d.\nInput < y or n > :\n" % slotemu
                    restart_hard = self.get_the_customer_input(note)
                    
                    if restart_hard == "Y": 
                        print "\n%s is restart hard now , slot:%d, wait for 5mins\n" % (cardtype, slotemu)
                        
                         
                        #复位过的从列表中删除
                        slot_emu_list.remove(slotemu)
                         
                        
                        self.restart_card_hard(slotemu)
                    else:
                        print "\n%s is not restart , slot:%d" % (cardtype, slotemu)
                else:
                    if str_input == 'skip':
                        break
        
    def upgrade_pos_restart_pos(self):
        slot_restart_list = self.restart_slot_dic["N64F01"] + self.restart_slot_dic["N16F01"]
        slot_upgrade_list = self.upgrade_slot_pos_dic["N64F01"] + self.upgrade_slot_pos_dic["N16F01"]
        
        #升级POS板
        #循环显示需要升级的槽位，直到输入0结束该流程
        if [] != slot_upgrade_list:
            
            while [] != slot_upgrade_list:
                strupr = ''
                for slot in slot_upgrade_list:
                    strtemp = "\n%d: Slot%d upgrade CPLD now!" % (slot,slot)
                    strupr = strupr + strtemp
                note = "\n\n\nUpgrade POS CPLD（C0）\n Please select POS Card to execute card reboot.\n%s\nskip: Skip and move to next action.\n\nPlease input:" % strupr
                str_input = raw_input(note)
                
                if str_input.isdigit():
                    slotpos = int(str_input)
                    
                    """
                    if 0 == slotpos:
                        #槽位为0退出循环
                        break
                    """
                    #非列表中的槽位，继续
                    if slotpos not in slot_upgrade_list:
                        continue
                    while True:                                
                        if slotpos in slot_upgrade_list:
                            break
                        else:
                            str_input  = raw_input("Slot list:%s\nPlease input the valid slot:\n" % slot_upgrade_list)
                            
                            if str_input.isdigit():
                                slotpos = int(str_input)
                    
                    note = "\nPlease confirm it again.It will execute upgrade CPLD and reboot on slot %d.\nInput < y or n > :" % slotpos
                    restart_hard = self.get_the_customer_input(note)
                    
                    if restart_hard == "Y":         
                        #升级过的从列表中删除，并从复位列表中删除
                        slot_upgrade_list.remove(slotpos)
                        slot_restart_list.remove(slotpos)
                        
                        print "\nUpgrade CPLD now , Please wait!\n"
                        if self.download_pos_cpld(slotpos):
                            print "Upgrade CPLD success slot:%d!\n" % slotpos
                            self.info_show(self.log_node_success, "after upgrade opca, POS slot:%d CPLD download success.\n" % slotpos)
                        else:
                            print "Upgrade fail slot:%d!\n" % slotpos
                            self.info_show(self.log_node_fail, "after upgrade opca, POS slot:%d CPLD download fail.\n" % slotpos) 
                    else:
                        print "\n%s is not upgrade , slot:%d" % slotpos
                else:
                    if str_input == 'skip':
                        break
                    
        
        else:
            print "\n\n\nThere is no C0 card for upgarde CPLD, go to restart hard flow!\n"
            
        if [] !=  slot_restart_list:       
            #复位POS板
            while [] != slot_restart_list:
                strupr = ''
                for slot in slot_restart_list:
                    strtemp = "\n%d: Slot%d restart hard now!" % (slot,slot)
                    strupr = strupr + strtemp
                note = "\n\n\nSelect which POS card you want to reboot?\n%s\nskip: Skip and move to next action.\n\nPlease input:" % strupr
                str_input = raw_input(note)
                
                if str_input.isdigit():
                    slotpos = int(str_input)
                    
                    """
                    if 0 == slotpos:
                        #槽位为0退出循环
                        break
                    """
                    
                    #非列表中的槽位，继续
                    if slotpos not in slot_restart_list:
                        continue
                    
                    while True:                                
                        if slotpos in slot_restart_list:
                            break
                        else:
                            str_input  = raw_input("Slot list:%s\nPlease input the valid slot:\n" % slot_restart_list)
                            
                            if str_input.isdigit():
                                slotpos = int(str_input)
 
                    note = "\nPlease confirm it again.It will execute reboot on slot %d.\nInput < y or n > :" % slotpos
                    restart_hard = self.get_the_customer_input(note)
                    
                    if restart_hard == "Y":         
                        #复位过的从列表中删除
                        slot_restart_list.remove(slotpos)
    
                        print "Pos is restart hard now , slot:%d, wait for 5mins\n" % slotpos
                        self.restart_card_hard(slotpos)            
                    else:
                        print "Pos is not restart hard!\n" % slotpos
                else:
                    if str_input == 'skip':
                        break
                        
    def script_login(self):
        #用户登录
        while True:
            usr = raw_input("UserName: \n")
            pwd = getpass.getpass("PassWord: \n") 
            
            if (usr == "root" and pwd == "sons0ns.n") or (usr == "root" and pwd == "root"):
                #更新6000端口密码
                support_port_dic[6000][2] = pwd
                return True
            else:
                note = "Try again? Input<y or n>"
                rtn = self.get_the_customer_input(note)
                if rtn.upper() == "Y":
                    continue
                else:
                    return False
    
    def _execute(self):        
        self.work_path = self.options.path
        self.md5 = self.options.md5
        self.autoupgrade = self.options.autoupgrade
        self.bios = self.options.bios
        self.cpld = self.options.cpld
        self.iplistfile = self.options.cfgfile
        self.md5file = self.options.md5file
        self.onlycpld = self.options.onlycpld
        
        self.versionlistfile = self.options.verlistfile
        
        self.info_init()
        
        #单独计算BIOS和CPLD的MD5
        self.md5_list = self.cpld_bios_md5_list()
        
        #获取操作员的编号，用于创建文件夹保存log文件
        self.logfolder  = raw_input("Please Input Log Folder Name: \n")
        
        if self.script_login() != True:
            print "\n\n\nYou choose quit script!\n\n\n"
            return True
        
        #将BIOS 和 CPLD文件加入到dic，并且不带MD5校验，需要在校验前删掉
        self.upgrade_file_dic = {
            "OPCA"  : [
            [r"/tffs/sys", r"upgrade.txt",           self.work_path+r'/705upgrade',        r"upgrade.txt"],
            [r"/tffs/sys", r"tn705opca.img",         self.work_path+r'/705upgrade',        r"tn705opca.img"],            
            [r"/tffs/sys", r"mospec.dat",            self.work_path+r'/705upgrade',        r"mospec.dat"],
            [r"/tffs/sys", r"tbldata.dat",           self.work_path+r'/705upgrade',        r"tbldata.dat"],
            [r"/tffs/sys", r"tblspec.dat",           self.work_path+r'/705upgrade',        r"tblspec.dat"],
            [r"/tffs/sys", r"ZEBOS.CFG",             self.work_path+r'/705upgrade',        r"ZEBOS.CFG"],
            [r"/tffs/sys", r"snmpd.conf",            self.work_path+r'/705upgrade',        r"snmpd.conf"],
            [r"/tffs/sys", r"netring.ini",           self.work_path+r'/705upgrade',        r"netring.ini"],        
            [r"/tffs/sys", r"QTR6081V0.F([\da-f]+)", self.work_path+r'/705upgrade',        r"QTR6081V0.F([\da-f]+)"],            
            [r"/tffs/sys", r"QTR6082V0.F([\da-f]+)", self.work_path+r'/705upgrade',        r"QTR6082V0.F([\da-f]+)"],
            [r"/tffs/sys", r"QTR6082V1.F([\da-f]+)", self.work_path+r'/705upgrade',        r"QTR6082V1.F([\da-f]+)"],
            [r"/tffs/sys", r"qtr6083V0.F([\da-f]+)", self.work_path+r'/705upgrade',        r"qtr6083V0.F([\da-f]+)"],
            [r"/tffs/sys", r"tn705pos.img",          self.work_path+r'/705upgrade',        r"tn705pos.img"],
            [r"/tffs/sys", r"S6085G10.F([\da-f]+)",  self.work_path+r'/705upgrade',        r"S6085G10.F([\da-f]+)"],
            [r"/tffs/sys", r"S6085F16S.F([\da-f]+)", self.work_path+r'/705upgrade',        r"S6085F16S.F([\da-f]+)"],
            [r"/tffs/sys", r"S6085F1S.F([\da-f]+)",  self.work_path+r'/705upgrade',        r"S6085F1S.F([\da-f]+)"],
            [r"/tffs/sys", self.bios_name,           self.work_path+r'/BIOS',              self.bios_name],
            [r"/tffs/sys", self.cpld_name        ,   self.work_path+r'/CPLD',              self.cpld_name],
            [r"/tffs/sys", r"filelist.txt",          self.work_path+r'/705upgrade',        r"filelist.txt"],        
            ],
            "N64F01"  : [
            [r"/tffs/sys", self.cpld_name,           self.work_path+r'/CPLD',              self.cpld_name],
            ],
            "N16F01"  : [
            [r"/tffs/sys", self.cpld_name,           self.work_path+r'/CPLD',              self.cpld_name],
            ]
        }
        
        worktime = str(datetime.datetime.now())
        self.worktime = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        self.info_show(log_node_summary, "The upgrade file operation begin time %s \n"%(self.worktime)) 
        
        #dwongrade for 15 and 13
        if self.onlycpld == "True":
            if(self.autoupgrade == "True"):
                FtpFile = "Y"
            else:
                #可以考虑是用户输入选择
                note = "Downgrade only for 15 and 13sp1, only ftp cpld file to pos!\nInput < y or n > :\nplease input:"
                FtpFile = self.get_the_customer_input(note)
                
            #ftp传送文件功能    
            if FtpFile == "Y":
                #首先得到IP list
                ip_list = self.get_iplist()
                
                #上传文件批处理，将CPLD、BIOS、SW传输到主控板，再将需要升级的CPLD传输到POS板作准备 
                for ip in ip_list:
                    #初始化成员变量
                    self.init_member_variables()
                    self.set_ne_ip(0, ip)
                    self.tnxxx.disconnect()
                    
                    #先初始化一下变量
                    ftp_results_dic[ip] = "fail"
                    
                    #得到升级用到的所有字典
                    if not self.get_restart_slot_information():
                        print "\n\nGet the ne %s information occur error, may be there is one opca, check the ne status!\n\n" % ip
                        self.info_show(self.log_node_fail, "Get the ne %s information occur error, may be there is one opca, check the ne status!\n" % ip)
                        self.info_show(log_node_summary, "ftp cpld file" + log_summary_fail % ip)
                        continue
                    
                    #ftp传送文件POS
                    if self.ftp_file_to_pos():
                        #记录成功
                        self.info_show(log_node_summary, "ftp cpld file" + log_summary_success % ip)
                        #记录每个IP的ftp过程是否成功
                        ftp_results_dic[ip] = "success"
                    else:
                        self.info_show(log_node_summary, "ftp cpld file" + log_summary_fail % ip)
                        ftp_results_dic[ip] = "fail"
                
                #提示传文件成功失败的汇总
                for ip in ip_list:
                    if ftp_results_dic[ip] == "success":
                        print "ip:%s ftp cpld file success!\n" % ip
                    else:
                        print "ip:%s ftp cpld file fail!\n" % ip
                
        else:
            if(self.autoupgrade == "True"):
                FtpFile = "Y"
            else:
                #可以考虑是用户输入选择
                note = "Ftp file to NE in iplist file!\nInput < y or n > :\nplease input:"
                FtpFile = self.get_the_customer_input(note)
                
            #ftp传送文件功能    
            if FtpFile == "Y":
                #首先得到IP list
                ip_list = self.get_iplist()
                
                #上传文件批处理，将CPLD、BIOS、SW传输到主控板，再将需要升级的CPLD传输到POS板作准备 
                for ip in ip_list:
                    #初始化成员变量
                    self.init_member_variables()
                    self.set_ne_ip(0, ip)
                    self.tnxxx.disconnect()
                    
                    #先初始化一下变量
                    ftp_results_dic[ip] = "fail"
                    
                    #得到升级用到的所有字典
                    if not self.get_restart_slot_information():
                        print "\n\nGet the ne %s information occur error, may be there is one opca, check the ne status!\n\n" % ip
                        self.info_show(self.log_node_fail, "Get the ne %s information occur error, may be there is one opca, check the ne status!\n" % ip)
                        self.info_show(log_node_summary, "ftp cpld file" + log_summary_fail % ip)
                        continue
                    
                    #ftp传送文件
                    if self.ftp_file_to_opca_and_pos():
                        #记录成功
                        self.info_show(log_node_summary, "ftp file" + log_summary_success % ip)
                        #记录每个IP的ftp过程是否成功
                        ftp_results_dic[ip] = "success"
                    else:
                        self.info_show(log_node_summary, "ftp file" + log_summary_fail % ip)
                        ftp_results_dic[ip] = "fail"
                
                #提示传文件成功失败的汇总
                for ip in ip_list:
                    if ftp_results_dic[ip] == "success":
                        print "ip:%s ftp file success!\n" % ip
                    else:
                        print "ip:%s ftp file fail!\n" % ip
        
        if(self.autoupgrade == "True"):
            UpgradeFlow = "Y"
        else:
            #可以考虑是用户输入选择    
            note = "Upgrade NE one by one in the iplist!\nInput < y or n > :\nplease input:"
            UpgradeFlow = self.get_the_customer_input(note)
            
        #升级软件功能    
        if UpgradeFlow == "Y":
            #首先得到IP list
            ip_list = self.get_iplist()
            
            #得到期望的版本号用于升级后的校验
            self.card_version_dic = self.get_dest_version_dic()
            
            for ip in ip_list:
                #初始化成员变量
                self.init_member_variables()
                self.set_ne_ip(0, ip)
                self.tnxxx.disconnect()
                
                #得到升级用到的所有字典
                if not self.get_restart_slot_information():
                    print "\n\nGet the ne %s information occur error, may be there is one opca, check the ne status!\n\n" % ip
                    self.info_show(self.log_node_fail, "Get the ne %s information occur error, may be there is one opca, check the ne status!\n" % ip)
                    continue
                
                #升级OPCA bios
                self.get_bios_file_and_slot()
                
                   
                #for the test
                
                """
                self.check_version_new()
                self.upgrade_pos_restart_pos()
                self.choose_restart_hard_emu("CM48E16")
                """
                 
                if(self.autoupgrade == "True"):
                    start_upgrade_flow = "Y"
                else:
                    note = "Start upgrade flow for NE ip: %s!\nInput < y or n > :\nplease input:" % ip
                    start_upgrade_flow = self.get_the_customer_input(note)
                    
                #是否启动网元的升级--yes
                if start_upgrade_flow == "Y":    
                    
                                        
                    #standby bios--yes
                    print "The Ne is writting standby opca'bios, waitting...\n"
                    if self.download_standby_opca_bios():
                        print "Upgrade standby opca'bios success!\n"
                        self.info_show(self.log_node_success, "download standby opca bios success.\n")
                        
                        if(self.autoupgrade == "True"):
                            restart_opca = "Y"
                        else:
                            note = "Restart NE ip: %s standby opca!\nInput < y or n > :\nplease input:" % ip
                            restart_opca = self.get_the_customer_input(note)
                            
                        #是否复位standby opca--yes
                        if restart_opca == "Y":
                            print "Standby opca is restart hard now, wait for 5 minutes!\n"
                             
                            self.restart_card_hard(self.slot_backupsys_list[1][0])
                             
                            #是否同步--yes
                            print "After standby opca is restart hard, check the sync information!\n"
                            if self.wait_ne_sync():
                                print "Sync success!\n"
                                
                                if(self.autoupgrade == "True"):
                                    upgrade_active_opca = "Y"
                                else:
                                    note = "Continue the active opca's upgrade flow!\nInput < y or n > :\nplease input:"
                                    upgrade_active_opca = self.get_the_customer_input(note)
                                    
                                if upgrade_active_opca == "Y":                                    
                                    self.info_show(self.log_node_success, "after upgrade bios, standby opca is sync success.\n")
                                    print "The Ne is writting active opca'bios, waitting...\n"
                                    
                                    #active bios--yes
                                    if self.download_active_opca_bios():
                                        print "Upgrade active opca'bios success!\n"
                                        self.info_show(self.log_node_success, "download active opca bios success.\n")
                                        
                                        #是否复位active opca--yes                                    
                                        if(self.autoupgrade == "True"):
                                            restart_opca = "Y"
                                        else:
                                            note =  "Restart NE ip: %s active opca!\nInput < y or n > :\nplease input:" % ip
                                            restart_opca = self.get_the_customer_input(note)
                                            
                                        if restart_opca == "Y":
                                            print "Active opca is restart hard now, wait for 5 minutes!\n"
                                             
                                            self.restart_card_hard(self.slot_backupsys_list[0][0])
                                             
                                            #是否同步--yes
                                            if self.wait_ne_sync():
                                                print "Sync success!\n"
                                                self.info_show(self.log_node_success, "after upgrade bios, active opca is sync success.\n")
    
                                                #自动化的时候就自动复位
                                                if(self.autoupgrade == "True"):
                                                    #升级POS并复位
                                                    for slot in self.restart_slot_dic["N64F01"] + self.restart_slot_dic["N16F01"]:#restart_slot_dic所有当前的POS
                                                        if slot in self.upgrade_slot_pos_dic["N64F01"] + self.upgrade_slot_pos_dic["N16F01"]:#upgrade_slot_pos_dic需要升级的POS                        
                                                            #需要升级的POS是否升级CPLD
                                                            print "Upgrade CPLD of POS slot:%d!\n" % slot
                                                            #POS升级成功--yes
                                                            if self.download_pos_cpld(slot):
                                                                print "Upgrade success slot:%d!\n" % slot
                                                                self.info_show(self.log_node_success, "after upgrade opca, POS slot:%d CPLD download success.\n" % slot)
                                                                #POS升级成功
                                                            #POS升级成功--no
                                                            else:
                                                                print "Upgrade fail slot:%d!\n" % slot
                                                                self.info_show(self.log_node_fail, "after upgrade opca, POS slot:%d CPLD download fail.\n" % slot)                                                            
                                                        #需要升级的POS--no
                                                        else:
                                                            #不需要升级的POS是否复位
                                                                print "Pos is restart hard now , slot:%d, wait for 5mins" % slot
                                                                self.restart_card_hard(slot)
                                                    
                                                    #复位仿真板
                                                    for slot in self.restart_slot_dic["CM48E16"] + self.restart_slot_dic["CM48E16S"]:
                                                        print "restart hard now , slot:%d, wait for 5mins" % slot
                                                        self.restart_card_hard(slot)
                                                else:
                                                    #升级和复位POS单板
                                                    self.upgrade_pos_restart_pos()
                                                    
                                                    #复位仿真板
                                                    self.choose_restart_hard_emu("CM48E16")
                                                    self.choose_restart_hard_emu("CM48E16S")
                                                
                                            #是否同步--no
                                            else:
                                                print "Sync fail, check the ne!\n"
                                                self.info_show(self.log_node_fail, "after upgrade bios, active opca is sync fail.\n")
                                                continue
                                        #是否复位active opca--no
                                        else:
                                            continue
                                    #active bios--no        
                                    else:
                                        print "Upgrade active opca'bios fail!\n"
                                        continue
                                #the select for active opca-no
                                else:
                                    print "\n\nCancel the active opca's  upgrade flow!\n\n"
                                    continue
                            #是否同步--no
                            else:
                                print "Sync fail, check the ne!\n"
                                self.info_show(self.log_node_fail, "after upgrade bios, standby opca is sync fail.\n")
                                continue
                        #是否复位standby opca---no
                        else:
                            continue
                    #standby bios--no
                    else:
                        print "Upgrade standby opca'bios fail!\n"
                        self.info_show(self.log_node_fail, "download standby opca bios fail.\n")
                        continue 

                    if(self.autoupgrade == "True"):
                        check_version = "Y"
                    else:
                        note = "Check the ne version?\nInput < y or n > :\nplease input:"
                        check_version = self.get_the_customer_input(note)
                        
                    if check_version == "Y":
                        print "Check the version, Wait for 5 minutes!\n"
                        self.my_sleep(300)
                        
                        #检查所有版本号是否是期望的版本号,check_version返回值是字典，为空就代表升级成功
                        if  self.check_version_new():
                            #记录成功
                            self.info_show(log_node_summary, "upgrade flow" + log_summary_success % ip)
                            print "ip： %s upgrade success\n" % ip
                        else:
                            self.info_show(log_node_summary, "upgrade flow" + log_summary_fail % ip)
                            #将字典的内容记录到LOG文件中
                            print "ip： %s upgrade fail\n" % ip
                    else:
                        print "Cancel the ne version check"
                #是否启动网元的升级--no
                else:
                    continue
                
               
        worktime = str(datetime.datetime.now())
        self.worktime_end = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        
        self.info_show(log_node_summary, "The upgrade file operation end time %s "%(self.worktime_end))
        
        self.info_file_save()
        
        return True
    
if __name__ == "__main__" :
    case = TestCase()
    case.execute()